#pragma comment(linker, "/STACK:102400000,102400000")
// run: $exec < input
// opt: 0
// flag: -g
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>

void scan(int & a)
{
	a = 0;
	bool flag = false;
	char ch = std::getchar();
	if (ch == '-')
		flag = true;
	else if (ch >= '0' && ch <= '9')
		a = ch - '0';

	while ((ch = std::getchar()) >= '0' && ch <= '9')
		a = a * 10 + ch - '0';
	if (flag) a = -a;
}

struct edge
{
	int to;
	int rev; // 1 for rev, 2 for undir
	bool vis;
};
std::vector<std::vector<int>> g;

int const maxn = 1000007;
std::vector<edge> edges(maxn * 4);
bool vis[maxn];
int t1[maxn];
int t2[maxn];
int n, m1, m2;
int alloc = 0;

void init()
{
	alloc = 0;
	g.clear();
	g.resize(n + 1);
	for (int i = 0; i <= n; i++) t1[i] = t2[i] = vis[i] = 0;
}

void add_edge(int u, int v, int ty)
{
	edge tmp{v, 0, 0};
	if (!ty) tmp.rev = 2;
	g[u].push_back(alloc);
	edges[alloc++] = tmp;
	tmp.to = u;
	if (ty == 1) tmp.rev = 1;
	g[v].push_back(alloc);
	edges[alloc++] = tmp;
}

bool dfs(int u)
{
	vis[u] = true;
	for (auto id : g[u]) {
		edge & e = edges[id];
		if (e.vis) continue;
		e.vis = edges[id ^ 1].vis = true;
		int v = e.to;
		int tt2 = t2[u], tt1 = t1[u];
		if (e.rev == 1) tt2++;
		else if (!e.rev) tt1++;

		if (vis[e.to]) {
			tt2 -= t2[v];
			tt1 -= t1[v];
			if (!tt2 || !tt1) return true;
		} else {
			t1[v] = t1[u];
			t2[v] = t2[u];
			if (e.rev == 1) t2[v]++;
			else if (!e.rev) t1[v]++;
			if (dfs(v)) return true;
		}
	}
	return false;
}

int main()
{
	int T; scan(T);
	while (T--) {
		scan(n); scan(m1); scan(m2);
		init();
		for (int i = 0, x, y; i < m1; i++) {
			scan(x); scan(y);
			add_edge(x, y, 0);
		}
		for (int i = 0, x, y; i < m2; i++) {
			scan(x); scan(y);
			add_edge(x, y, 1);
		}

		bool ok = false;
		for (int i = 1; i <= n; i++) {
			if (vis[i]) continue;
			if (dfs(i)) {
				ok = true; break;
			}
		}
		if (ok) printf("YES\n");
		else printf("NO\n");
	}
}

